//
// Created by 29001 on 2024/11/20.
//

#ifndef HANDWRITTEN_SQLITE_SIMPLE_SQL_COMPILER_H
#define HANDWRITTEN_SQLITE_SIMPLE_SQL_COMPILER_H

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<stdbool.h>
#include <errno.h>
#include <stdint.h>
#include "REPL.h"
#include "table.h"

/*
 * our new functions return enums indicating success or failure
 */
typedef enum {
    META_COMMAND_SUCCESS,
    META_COMMAND_UNRECOGNIZED_COMMAND,
} MetaCommandResult;

/*
 * our sql statement's type
 */
typedef enum {
    STATEMENT_INSERT,
    STATEMENT_SELECT,
} StatementType;


/*
 * indicating our Prepare result
 */
typedef enum {
    PREPARE_SUCCESS,
    PREPARE_SYNTAX_ERROR,
    PREPARE_UNRECOGNIZED_STATEMENT,
} PrepareResult;


/*
 * our sql statement
 */
typedef struct {
    StatementType type;
    Row row_to_insert;//only used by insert statement
} Statement;


/*
 * Handle the metadata, like .exit, our token must be match metadata first,then match the statement
 */
MetaCommandResult do_meta_command(InputBuffer *inputBuffer, Table *table);

/*
 * Handle our statement(not the metadata),this is our sql compiler
 * check our statement and so on
 */
PrepareResult prepare_statement(InputBuffer *input_buffer, Statement *statement);


/*
 * indicates the execute result
 */
typedef enum {
    EXECUTE_SUCCESS,
    EXECUTE_TABLE_FULL,
} ExecuteResult;

/*
 * here just really execute our statement now!
 */
ExecuteResult execute_insert(Statement *statement, Table *table);

ExecuteResult execute_select(Statement *statement, Table *table);

ExecuteResult execute_statement(Statement *statement, Table *table);

#endif //HANDWRITTEN_SQLITE_SIMPLE_SQL_COMPILER_H
